package com.magicborrow.utils;

import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.telephony.TelephonyManager;
import android.text.TextPaint;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 为了避免jar太多, 没用用apache的jar, 从以前公司项目里copy过来一个工具类... <br>
 * <i>没有对类里的方法进行删减, 如果需要可以以后处理</i>
 * 
 * 
 */
public class StringTools {

	public static final int FILL_LEADING = 0;
	public static final int FILL_ENDING = 1;
	/** 空字符 */
	public static final String EMPTY = "";

	public static final String BLANK_SPACE = " ";

/*	public static void setEmptyInfo(View view,int drawableId,String message){
		//RelativeLayout commonLayout = (RelativeLayout)view.findViewById(R.id.commonInfo);
		ImageView image = (ImageView)view.findViewById(R.id.imageInfo);
		TextView info = (TextView)view.findViewById(R.id.textInfo);
		image.setBackgroundResource(drawableId);
		info.setText(message);
		view.setVisibility(View.VISIBLE);
	}*/
	
	// 设置粗体（  后期不需要粗体 为了不改动太大 直接将true改为false）
	public static void setFakeBoldText(TextView tv){
		TextPaint tp = tv.getPaint();
		tp.setFakeBoldText(false);
	}

/*	// 时间转换 仅限乐艺网使用
	public static String formatDate(String str){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String strDate = str.replace("T", " ");
		Date date = null;
		String strd = "";
		try {
			date = sdf.parse(strDate);
			SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			strd = sd.format(date);

		} catch (ParseException e) {
			e.printStackTrace();
		}
		return strd;
	}
	// 时间转换 仅限乐艺网使用
	public static String formatDateLikeBrith(String str){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String strDate = str.replace("T", " ");
		Date date = null;
		String strd = "";
		try {
			date = sdf.parse(strDate);
			SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd日");
			strd = sd.format(date);
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return strd;
	}*/
/*
 * str格式3566.14
 */
	public static String formatPrice(String str)
	{
		if(str.contains(".")){
		String[] s =str.split("\\.");
		s[0] = mat(s[0]);
		if(s[1].equals("0")){
			return s[0]+".00";
		}else {
			return s[0]+"."+s[1];
		}
		}else{
			return  mat(str)+".00";
		}
	}
	private static String mat(String st){
		StringBuffer priceSt = new StringBuffer(st);

		int size = priceSt.length();
		
		if (size <= 3) {
			st=  priceSt.toString();
		} else {
			for (int i = size - 3; i > 0; i -= 3) {

				priceSt = priceSt.insert(i, ",");
			}

			st= priceSt.toString() ;
		}
		return st;
	}
	
	/*	// 将传进数字反转
		String reverseStr = new StringBuilder(str).reverse().toString();
		String strTemp = "";
		for (int i=0; i<reverseStr.length(); i++) {
			if (i*3+3 > reverseStr.length()) {
				strTemp += reverseStr.substring(i*3, reverseStr.length());
				break;
			}
			strTemp += reverseStr.substring(i*3, i*3+3)+",";
		}
		// 将 【789,456,】 中最后一个【,】去除
		if (strTemp.endsWith(",")) {
			strTemp = strTemp.substring(0, strTemp.length()-1);
		}
		// 将数字重新反转
		String resultStr = new StringBuilder(strTemp).reverse().toString();
		return resultStr;
		//最后再将顺序反转过来  
	 */	
	

	/**
	 * fills an empty character array with data from a character
	 */
	private static char[] fillString(int start, char[] out, char[] in, char fillValue) {
		int inCount = 0;
		for (int i = start; i < out.length; i++) {
			if (inCount < in.length) {
				out[i] = in[inCount++];
			} else {
				out[i] = fillValue;
			}
		}
		return out;
	}

	/**
	 * Accepts a string of variable length and returns it as a String of length
	 * numChars
	 * 
	 * @param s
	 *            String to be fixed to a certain length
	 * @param numChars
	 *            Number of characters to fix the strings length to
	 * @return String passed in of fixed length. extra chars in original string
	 *         truncated
	 */
	public static String fixedStringFormat(String s, int numChars) {
		char[] in = s.toCharArray();
		char[] out = new char[numChars];
		out = fillString(0, out, in, ' ');
		return new String(out);
	}

	/**
	 * Accests a string of variable length and returns is as a String of length
	 * numChars. Pads empty characters with param proviede
	 * 
	 * @param s
	 *            String to be fixed to a certain length
	 * @param numChars
	 *            Number of characters to fix the strings length to
	 * @param fillValue
	 *            Character to pad empty characters with
	 * @param fillType
	 *            integer representing the type of Pad to perform (LEADING,
	 *            ENDING chars)
	 * @return String passed in of fixed length. extra chars in original string
	 *         truncated
	 */
	public static String fixedStringFormat(String s, int numChars, char fillValue, int fillType) {
		char[] in = s.toCharArray();
		char[] out = new char[numChars];
		int start = 0;
		if (fillType == FILL_LEADING) {
			int diff = out.length - in.length;
			if (diff > 0) {
				Arrays.fill(out, 0, diff, fillValue);
				start = diff;
			}
		}
		out = fillString(start, out, in, fillValue);
		return new String(out);
	}

	/**
	 * Splits a string on a delimiter
	 * 
	 * @param s
	 *            string to split
	 * @param delim
	 *            delimiter to spit string on
	 * @return an array containing values of the split. returns null if nothing
	 *         split
	 */
	public static String[] split(String s, String delim) {
		ArrayList list = new ArrayList();
		int firstIndex = s.indexOf(delim);
		if (firstIndex < 0)
			return new String[] { s };
		if (firstIndex > 0)
			list.add(s.substring(0, firstIndex));
		while (firstIndex > -1) {
			int startPos = firstIndex;
			int nextIndex = s.indexOf(delim, firstIndex + 1);
			firstIndex = nextIndex;
			if (nextIndex == -1)
				nextIndex = s.length();
			String substr = s.substring((startPos + delim.length()), nextIndex);
			list.add(substr);
		}
		String[] str = new String[list.size()];
		for (int i = 0; i < list.size(); i++) {
			str[i] = (String) list.get(i);
		}
		return str;
	}

	/**
	 * merget to StringList to String
	 * 
	 * @param al
	 * @param delim
	 * @return
	 */
	public static String mergeStringList(ArrayList<String> al, String delim) {
		if (al == null)
			return null;
		if (al.size() < 1)
			return "";
		StringBuffer sb = new StringBuffer(al.get(0));
		for (int i = 1; i < al.size(); i++) {
			sb.append(delim);
			sb.append(al.get(i));
		}
		return sb.toString();
	}

	/**
	 * Splits a string on a delimiter
	 * 
	 * @param list
	 *            ArrayList to be used to store data
	 * @param s
	 *            string to split
	 * @param delim
	 *            delimiter to spit string on
	 * @return ArrayList with split results appended. returns list if nothing to
	 *         split
	 */

	public static ArrayList split(ArrayList list, String s, String delim) {
		int firstIndex = s.indexOf(delim);
		if (firstIndex < 0)
			return list;
		if (firstIndex > 0)
			list.add(s.substring(0, firstIndex));
		while (firstIndex > -1) {
			int startPos = firstIndex;
			int nextIndex = s.indexOf(delim, firstIndex + 1);
			firstIndex = nextIndex;
			if (nextIndex == -1)
				nextIndex = s.length();
			String substr = s.substring((startPos + delim.length()), nextIndex);
			list.add(substr);
		}
		return list;
	}

	/**
	 * Returns true if the String is null or empty.
	 * 
	 * @param str
	 *            String to check
	 * @return true- is null or empty false - is not null or empty.
	 */
	public static boolean isNullOrEmpty(String str) {
		return str == null || str.trim().compareTo("") == 0 || str.equals("null");
	}

	/**
	 * 如果字符不为空, 返回true; 否则false<br>
	 * 效果等于 <code>!isEmpty(str)</code>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * Converts an object to a string representation that lists all of the
	 * fields.
	 * 
	 * @param obj
	 *            an object
	 * @return a string with the object's class name and all field names and
	 *         values;
	 */
	public static String toString(Object obj) {
		Class c = obj.getClass();
		String r = c.getName();

		// inspect the fields of this class and all superclasses
		do {
			r += "[";
			Field[] fields = c.getDeclaredFields();
			AccessibleObject.setAccessible(fields, true);
			// get the names and values of all fields
			for (int i = 0; i < fields.length; i++) {
				Field f = fields[i];
				r += f.getName() + "=";
				try {
					Object val = f.get(obj);
					r += val.toString();
				} catch (Exception e) {
					continue;
				}
				if (i < fields.length - 1)
					r += ",";
			}
			r += "]";
			c = c.getSuperclass();
		} while (c instanceof Class);
		return r;
	}

	/**
	 * 由于String.subString对汉字处理存在问题（把一个汉字视为一个字节)，因此在 包含汉字的字符串时存在隐患，现调整如下：
	 * 
	 * @param src
	 *            要截取的字符串
	 * @param start_idx
	 *            开始坐标（包括该坐标)
	 * @param end_idx
	 *            截止坐标（包括该坐标）
	 * @return
	 */
	public static String substring(String src, int start_idx, int end_idx) {
		byte[] b = src.getBytes();
		String tgt = "";
		for (int i = start_idx; i <= end_idx; i++) {
			tgt += (char) b[i];
		}
		return tgt;
	}

	public static String replaceAll(String str, String target, String replacement) {
		String result = str;
		if (target.length() > 1 && target.startsWith("\\")) {
			target = target.substring(1);
		}
		// log.info("-------------------- target: " + target);
		while (result.indexOf(target) > -1) {
			result = result.replace(target, replacement);
			// log.info("-------------------- result: " + result);
		}

		return result;
	}

	/**
	 * Encode a string using algorithm specified in web.xml and return the
	 * resulting encrypted password. If exception, the plain credentials string
	 * is returned
	 * 
	 * @param password
	 *            Password or other credentials to use in authenticating this
	 *            username
	 * @param algorithm
	 *            Algorithm used to do the digest
	 * @return encypted password based on the algorithm.
	 */
	public static String encodePassword(String password, String algorithm) {
		byte[] unencodedPassword = password.getBytes();

		MessageDigest md;

		try {
			// first create an instance, given the provider
			md = MessageDigest.getInstance(algorithm);
		} catch (Exception e) {
			e.printStackTrace();
			return password;
		}

		md.reset();

		// call the update method one or more times
		// (useful when you don't know the size of your data, eg. stream)
		md.update(unencodedPassword);

		// now calculate the hash
		byte[] encodedPassword = md.digest();

		StringBuffer buf = new StringBuffer();

		for (int i = 0; i < encodedPassword.length; i++) {
			if (((int) encodedPassword[i] & 0xff) < 0x10) {
				buf.append("0");
			}

			buf.append(Long.toString((int) encodedPassword[i] & 0xff, 16));
		}

		return buf.toString();
	}

	public static String toPlainText(String htmlString) {
		if (htmlString == null || htmlString.trim().length() == 0)
			return "";
		String plainString = htmlString;
		plainString = plainString.replaceAll("<[^>]*>", "");
		plainString = plainString.replaceAll("&lt;", "<");
		plainString = plainString.replaceAll("&gt;", ">");
		plainString = plainString.replaceAll("&quot;", "\"");
		plainString = plainString.replaceAll("&nbsp;", " ");
		plainString = plainString.replaceAll("&amp;", "&");
		plainString = plainString.replaceAll("\\n|\\r", "");
		return plainString;
	}

	public static String toPlainTextIncludeCss(String htmlString) {
		if (htmlString == null || htmlString.trim().length() == 0)
			return "";
		String plainString = htmlString;
		// plainString = plainString.replaceAll("<style[^>]*>.*</style>", "");
		int begin = -1;
		while ((begin = plainString.indexOf("<style")) > -1) {
			// int begin = plainString.indexOf("<style");
			int last = plainString.indexOf("</style>");
			if (begin > -1 && last > -1) {
				plainString = plainString.substring(0, begin) + plainString.substring(last + 8);
			}
		}
		plainString = plainString.replaceAll("<[^>]*>", "");
		plainString = plainString.replaceAll("&lt;", "<");
		plainString = plainString.replaceAll("&gt;", ">");
		plainString = plainString.replaceAll("&quot;", "\"");
		plainString = plainString.replaceAll("&nbsp;", " ");
		plainString = plainString.replaceAll("&amp;", "&");
		plainString = plainString.replaceAll("&copy;", "Copyright");
		plainString = plainString.replaceAll("\\n|\\r", "");
		return plainString;
	}

	public static String toPlainTextWithoutNewLine(String htmlString) {
		if (htmlString == null || htmlString.trim().length() == 0)
			return "";
		String plainString = htmlString;
		plainString = plainString.replaceAll("<[^>]*>", "");
		plainString = plainString.replaceAll("&lt;", "<");
		plainString = plainString.replaceAll("&gt;", ">");
		plainString = plainString.replaceAll("&quot;", "\"");
		plainString = plainString.replaceAll("&nbsp;", " ");
		plainString = plainString.replaceAll("&amp;", "&");
		// plainString = plainString.replaceAll("\\n|\\r", "");
		return plainString;
	}

	/**
	 * Split one line of csv file
	 * 
	 * @param src
	 * @return String[]
	 * @throws Exception
	 */
	public static String[] splitCSV(String src) throws Exception {
		if (src == null || src.equals(""))
			return new String[0];
		StringBuffer st = new StringBuffer();
		Vector result = new Vector();
		boolean beginWithQuote = false;
		for (int i = 0; i < src.length(); i++) {
			char ch = src.charAt(i);
			if (ch == '\"') {
				if (beginWithQuote) {
					i++;
					if (i >= src.length()) {
						result.addElement(st.toString());
						st = new StringBuffer();
						beginWithQuote = false;
					} else {
						ch = src.charAt(i);
						if (ch == '\"') {
							st.append(ch);
						} else if (ch == ',') {
							result.addElement(st.toString());
							st = new StringBuffer();
							beginWithQuote = false;
						} else {
							throw new Exception("Single double-quote char mustn't exist in filed "
									+ (result.size() + 1) + " while it is begined with quote\nchar at:" + i);
						}
					}
				} else if (st.length() == 0) {
					beginWithQuote = true;
				} else {
					throw new Exception("Quote cannot exist in a filed which doesn't begin with quote!\nfield:"
							+ (result.size() + 1));
				}
			} else if (ch == ',') {
				if (beginWithQuote) {
					st.append(ch);
				} else {
					result.addElement(st.toString());
					st = new StringBuffer();
					beginWithQuote = false;
				}
			} else {
				st.append(ch);
			}
		}
		if (st.length() != 0) {
			if (beginWithQuote) {
				throw new Exception("last field is begin with but not end with double quote");
			} else {
				result.addElement(st.toString());
			}
		}
		String rs[] = new String[result.size()];
		for (int i = 0; i < rs.length; i++) {
			rs[i] = (String) result.elementAt(i);
		}
		return rs;
	}

	/**
	 * Split one line of csv file without exceptions.
	 * 
	 * @param src
	 * @return String[] splited fields
	 */
	public static String[] splitCSV2(String src) {
		if (src == null || src.equals(""))
			return new String[0];
		ArrayList result = new ArrayList();
		int i = 0;
		while (i < src.length()) {
			boolean beginWithQuote;
			int count = countContinuousQuote(i, src);
			if (count % 2 == 0) {
				beginWithQuote = false;
				i = i + count / 2;
			} else {
				beginWithQuote = true;
				// i = i+count-1;
			}
			if (beginWithQuote) {
				// till next quote and then till next comma after the index of
				// quote
				int nextQuote = src.indexOf('\"', i + 1);
				int quoteCount;
				if (nextQuote != -1) {
					do {
						quoteCount = countContinuousQuote(nextQuote, src);
						// assert quoteCount >= 1;
						if (quoteCount % 2 == 0) {
							nextQuote = src.indexOf('\"', nextQuote + quoteCount);
							if (nextQuote == -1)
								break;
						} else {
							nextQuote = nextQuote + quoteCount - 1;
							break;
						}
					} while (true);
				}
				if (nextQuote == -1) {
					// row over
					result.add(src.substring(i).replaceAll("\"\"", "\""));
					break;
				} else {
					int nextComma = src.indexOf(',', nextQuote);
					if (nextComma == -1) {
						// row over
						result.add(src.substring(i + 1).replaceAll("\"\"", "\""));
						break;
					} else {
						// column over
						result.add(src.substring(i + 1, nextComma - 1).replaceAll("\"\"", "\""));// nextComma-1
						// <=>
						// nextComma
						// -
						// "\",".length
						// +
						// 1
						i = nextComma + 1;
						if (i >= src.length()) {
							result.add("");
							break;
						}
					}
				}
			} else {
				// till next comma
				int comma = src.indexOf(',', i);
				if (comma == -1) {
					// row over
					result.add(src.substring(i));
					break;
				} else {
					// column over
					result.add(src.substring(i, comma));
					i = comma + 1;
					if (i >= src.length()) {
						result.add("");
						break;
					}
				}
			}
		}

		String rs[] = new String[result.size()];
		for (int j = 0; j < rs.length; j++) {
			rs[j] = (String) result.get(j);
		}
		return rs;
	}

	private static int countContinuousQuote(int startIndex, String src) {
		int count = 0;
		for (int i = startIndex; i < src.length(); i++) {
			char ch = src.charAt(i);
			if (ch == '\"')
				count++;
			else
				break;
		}
		return count;
	}

	public static String[] split(String value) {
		return splitWithSpacesQuoteSensitive2(value);
	}

	private static String[] splitWithSpacesQuoteSensitive1(String value) {
		value = trim(value);
		Pattern p = Pattern.compile("[\"]([^\"])*[\"]");
		Matcher m = p.matcher(value);
		List list = new ArrayList();
		while (m.find()) {
			String group = m.group();
			list.add(group.substring(1, group.length() - 1));

		}
		value = p.matcher(value).replaceAll(" ");
		String[] temp = value.split("(\\s|\u3000)+");
		for (int i = 0; i < temp.length; i++) {
			if (isNotEmpty(temp[i])) {
				list.add(temp[i]);
			}
		}
		for (int i = list.size() - 1; i >= 0; i--) {
			String s = (String) list.get(i);
			if (isNullOrEmpty(s))
				list.remove(i);
		}
		String[] result;
		result = (String[]) list.toArray(new String[0]);
		return result;
	}

	private static String[] splitWithSpacesQuoteSensitive2(String value) {
		boolean quoteStart = false;
		List list = new ArrayList();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < value.length(); i++) {
			char c = value.charAt(i);
			switch (c) {
			case ' ':
			case '\u3000':
				if (quoteStart) {
					sb.append(c);
				} else {
					if (sb.length() != 0) {
						list.add(sb.toString());
						sb = new StringBuffer();
					}
				}
				break;
			case '\"':
				if (quoteStart) {
					if (sb.length() != 0) {
						list.add(sb.toString());
						sb = new StringBuffer();
					}
					quoteStart = false;
				} else {
					if (sb.length() != 0) {
						list.add(sb.toString());
						sb = new StringBuffer();
					}
					quoteStart = true;
				}
				break;
			default:
				sb.append(c);
				break;
			}
		}
		if (sb.length() != 0) {
			list.add(sb.toString());
		}
		for (int i = list.size() - 1; i >= 0; i--) {
			String s = (String) list.get(i);
			if (isNullOrEmpty(s))
				list.remove(i);
		}
		return (String[]) list.toArray(new String[0]);
	}

	public static String formatNull(String str) {
		return nullToEmpty(str);
	}

	public static String nullToEmpty(String str) {
		return str == null ? "" : str;
	}

	/**
	 * @param bt
	 * @param encodeing
	 * @return
	 */
	public static String parseBytes(byte[] bt, String encodeing) {
		String s = null;
		try {
			s = new String(bt, encodeing);
		} catch (UnsupportedEncodingException e) {
			// logger.debug("Parse byte to String error",e);
		}
		return s;
	}

	/**
	 * @param bt
	 * @return
	 */
	public static String parseBytes(byte[] bt) {
		return parseBytes(bt, "UTF-8");
	}

	/**
	 * 将字符进行utf-8编码
	 * 
	 * @param input
	 * @return
	 */
	public static String encodeUTF8(String input) {
		return encode(input, "UTF-8");
	}

	/**
	 * @param input
	 * @return
	 */
	public static String encode(String input, String charset) {
		if (isNullOrEmpty(input))
			return input;
		try {
			return URLEncoder.encode(input, charset);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();;
		}
		return input;
	}

	/**
	 * @param input
	 * @return
	 */
	public static String decodeUTF8(String input) {
		return decode(input, "UTF-8");
	}

	public static String decode(String input, String coding) {
		if (isNullOrEmpty(input))
			return input;
		try {
			return URLDecoder.decode(input, coding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return input;
	}

	public static boolean isNumber(String input) {
		try {
			long temp = Long.parseLong(input);
		} catch (NumberFormatException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static String trim(String str) {
		str = str.trim();
		StringBuffer sb = new StringBuffer(str);
		while (sb.length() > 0 && sb.charAt(0) == '\u3000')
			sb = sb.deleteCharAt(0);
		while (sb.length() > 0 && sb.charAt(sb.length() - 1) == '\u3000')
			sb = sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}

	public static String[] splitWithCommaQuote(String value) {
		if (value == null || value.trim().equals("")) {
			return null;
		}

		boolean quoteStart = false;
		List list = new ArrayList();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < value.length(); i++) {
			char c = value.charAt(i);
			switch (c) {
			case '\uff0c':
				if (sb.length() != 0) {
					list.add(sb.toString());
					sb = new StringBuffer();
				}
				break;
			case ',':
				if (sb.length() != 0) {
					list.add(sb.toString());
					sb = new StringBuffer();
				}
				break;
			default:
				sb.append(c);
				break;
			}
		}
		if (sb.length() != 0) {
			list.add(sb.toString());
		}
		for (int i = list.size() - 1; i >= 0; i--) {
			String s = (String) list.get(i);
			if (isNullOrEmpty(s))
				list.remove(i);
		}
		return (String[]) list.toArray(new String[0]);
	}

	public static String formatDate(Date date) {

		SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd hh:mm");
		return df.format(date);
	}

	public static String substring(String str, int toCount) {
		int reInt = 0;
		String reStr = "";
		if (str == null)
			return "";
		char[] tempChar = str.toCharArray();
		for (int kk = 0; (kk < tempChar.length && toCount > reInt); kk++) {
			String s1 = str.valueOf(tempChar[kk]);
			byte[] b = s1.getBytes();
			reInt += b.length;
			reStr += tempChar[kk];
		}
		// if (toCount == reInt || (toCount == reInt - 1))
		// reStr += "...";
		return reStr;
	}

	public static int length(String str) {
		int length = 0;
		if (str == null)
			return 0;
		char[] tempChar = str.toCharArray();
		for (int kk = 0; kk < tempChar.length; kk++) {
			String s1 = str.valueOf(tempChar[kk]);
			byte[] b = s1.getBytes();
			length += b.length;
		}

		return length;
	}

	public static int strlength(String str) {
		return str.length();
	}

	public static String StrParse(String str, int len) {
		String[] resultStr = StrParse(new String[] { str }, len);

		return resultStr[0];
	}

	public static String[] StrParse(List str, int len) {
		String[] arrayStr = new String[str.size()];

		for (int i = 0; i < str.size(); i++) {
			arrayStr[i] = (String) str.get(i);
		}

		String[] resultStr = StrParse(arrayStr, len);

		return resultStr;
	}

	public static String[] StrParse(String[] str, int len) {
		Vector v = new Vector(0);
		int rstLen = len;
		int size = 0;

		for (int i = 0; i < str.length && rstLen > 0; i++) {
			String cnt = "";
			int charLen = length(str[i]);
			// System.out.println(charLen);
			if (rstLen > charLen) {
				// 总长度大于当前字符长度
				cnt = str[i];
				rstLen = rstLen - charLen;
				v.addElement(cnt);
				size++;
			} else {
				// 总长度小于或等于当前字符长度
				cnt = strByLen(str[i], rstLen, i == str.length - 1);// get part
				// of str
				v.addElement(cnt);
				size++;
				break;
			}
		}

		String[] s = new String[size];
		for (int k = 0; k < s.length; k++) {
			s[k] = v.elementAt(k).toString();
		}
		return s;
	}

	public static String strByLen(String str, int len, boolean isLastStr) {
		String showstr = "";
		int strLength = length(str);
		/*
		 * if the fist one is chinese of str, and the retlen=1,it can not show
		 * the chinese. if the last one is chinese of str, and there is only 1
		 * rest, so can not show the chinese two only there are more than 4 char
		 * left, need to show ... after the string.
		 */
		int length = 0;
		char[] tempChar = str.toCharArray();
		for (int kk = 0; length < len && kk < tempChar.length; kk++) {
			String s1 = str.valueOf(tempChar[kk]);
			showstr = showstr + s1;
			byte[] b = s1.getBytes();
			length += b.length;
		}

		if (strLength - 2 > len || (strLength - 2 == len && !isLastStr))
			// 服务器上多出2个字符
			showstr += "...";

		return showstr;
	}

	public static String replaceFCKEditorString(String target) {
		if (target == null)
			return "";

		target = target.replaceAll("&ldquo;", "“");
		target = target.replaceAll("&rdquo;", "”");
		target = target.replaceAll("<br />", "\n");
		return target;
	}

	/**
	 * This method takes a string which may contain URLs and replaces them with
	 * working links. It does this by adding the html tags &lt;a href&gt; and
	 * &lt;/a&gt;.
	 * <p/>
	 * don't need http or https auto convert, such as img src="http://" modified
	 * by banq
	 * <p/>
	 * The patterns recognized are <code>ftp://path-of-url</code>,
	 * <code>http://path-of-url</code>, <code>https://path-of-url</code>
	 * <code>[url path-of-url]descriptive text[/url]</code> and
	 * <code>[url=path-of-url]descriptive text[/url]</code> the
	 * <code>[url]</code> allows any path to be defined as link.
	 * 
	 * @param input
	 *            the text to be converted.
	 * @return the input string with the URLs replaced with links.
	 */
	public static String convertURL(String input, boolean newWindowEnabled) {
		// Check if the string is null or zero length
		// -- if so, return what was sent in.
		if (input == null || input.length() == 0) {
			return input;
		}

		// Build the response in a buffer
		StringBuffer buf = new StringBuffer(input.length() + 25);
		char[] chars = input.toCharArray();
		int len = input.length();

		int index = -1, i = 0;
		int j = 0, oldend = 0, k = 0;
		int u1, u2;
		char cur;

		// Handle the occurences of the ftp:// , http:// , https:// patterns
		// and the [url] pattern.
		while (++index < len) {
			cur = chars[i = index];

			// save valuable cpu resources by expanding the tests here instead
			// of calling String.indexOf()
			j = -1;
			if ((cur == 'f' && index < len - 6 && chars[++i] == 't' && chars[++i] == 'p')
					|| (cur == 'h' && (i = index) < len - 7 && chars[++i] == 't' && chars[++i] == 't'
					&& chars[++i] == 'p' && (chars[++i] == 's' || chars[--i] == 'p'))) {
				if (i < len - 4 && chars[++i] == ':' && chars[++i] == '/' && chars[++i] == '/') {
					j = ++i;
				}
			}

			// did we find http or ftp?
			if (j > 0) {
				// check context, dont handle patterns preceded by any of '"<=
				if (index == 0 || ((cur = chars[index - 1]) != '\'' && cur != '"' && cur != '<' && cur != '=')) {
					cur = chars[j];
					// now collect url pattern upto next " <\n\r\t"
					while (j < len) {
						// Is a space?
						if (cur == ' ')
							break;
						if (cur == '\t')
							break;
						// Is a quote?
						if (cur == '\'')
							break;
						if (cur == '\"')
							break;
						// Is html?
						if (cur == '<')
							break;
						if (cur == '[')
							break;
						// Is a Unix newline?
						if (cur == '\n')
							break;
						// Is Win32 newline?
						if (cur == '\r' && j < len - 1 && chars[j + 1] == '\n')
							break;
						// 中文
						if (input.valueOf(cur).getBytes()[0] < 0)
							break;
						//
						k = j;
						if ((cur == 'f' && j < len - 6 && chars[++k] == 't' && chars[++k] == 'p')
								|| (cur == 'h' && (k = j) < len - 7 && chars[++k] == 't' && chars[++k] == 't'
								&& chars[++k] == 'p' && (chars[++k] == 's' || chars[--k] == 'p'))) {
							if (k < len - 4 && chars[++k] == ':' && chars[++k] == '/' && chars[++k] == '/') {
								break;
							}
						}
						j++;
						if (j < len) {
							cur = chars[j];
						}
					}
					// Check the ending character of the URL. If it's a ".,)]"
					// then we'll remove that part from the URL.
					cur = chars[j - 1];
					if (cur == '.' || cur == ',' || cur == ')' || cur == ']') {
						j--;
					}
					buf.append(chars, oldend, index - oldend);
					buf.append("<a href=\"");
					buf.append(chars, index, j - index);
					buf.append('\"');
					if (newWindowEnabled) {
						buf.append(" target=\"_blank\"");
					}
					buf.append('>');

					buf.append(chars, index, j - index);
					buf.append("</a>");
				} else {
					buf.append(chars, oldend, j - oldend);
				}
				oldend = index = j;
			}
			// else if (cur == '[' && index < len - 6 &&
			// }
			/*
			 * if (cur == '[' && index < len - 6 && chars[i = index + 1] == 'u'
			 * && chars[++i] == 'r' && chars[++i] == 'l' && (chars[++i] == '='
			 * || chars[i] == ' ')) { j = ++i; u1 = u2 = input.indexOf("]", j);
			 * if (u1 > 0) { u2 = input.indexOf("[/url]", u1+1); } if (u2 < 0) {
			 * buf.append(chars, oldend, j-oldend); oldend = j; } else {
			 * buf.append(chars, oldend, index-oldend);
			 * buf.append("<a href =\""); buf.append(input.substring(j,
			 * u1).trim()); if (newWindowEnabled) {
			 * buf.append("\" target=\"_blank"); } buf.append("\">");
			 * buf.append(input.substring(u1+1, u2).trim()); buf.append("</a>");
			 * oldend = u2+6; } index = oldend; }
			 */
		}
		if (oldend < len) {
			buf.append(chars, oldend, len - oldend);
		}
		return buf.toString();
	}

	public static String formatInteger(int i, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(i);
	}

	public static String formatLong(long i, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(i);
	}

	public static String filterSpecialChar(String origin) {
		// 保留数字和字母
		origin = origin.replaceAll("\\W", "").replaceAll("_", "");
		return origin;
	}

	public static String replaceEnglishCommaWithChinese(String origin) {
		if (isNullOrEmpty(origin)) {
			return origin;
		}
		origin = origin.replaceAll(",", "，");
		return origin;
	}

	public static String urlOpenWithNewWindow(String oUrl) {
		int firstPos = oUrl.indexOf("<a", 0);
		int endPos = 0;
		int targetPos = 0;
		String strA = "";
		if (firstPos < 0)
			return oUrl;

		String nUrl = oUrl.substring(0, firstPos);
		while (firstPos >= 0) {
			endPos = oUrl.indexOf(">", firstPos);
			strA = oUrl.substring(firstPos, endPos + 1);
			if (strA.indexOf("\"_blank\"") > 0 || strA.indexOf("'_blank'") > 0) {
				nUrl = nUrl + strA;
			} else {
				nUrl = nUrl + oUrl.substring(firstPos, endPos) + " target=\"_blank\">";
			}
			firstPos = oUrl.indexOf("<a", endPos + 1);

			if (firstPos > endPos)
				nUrl = nUrl + oUrl.substring(endPos + 1, firstPos);
			else if (oUrl.length() > endPos)
				nUrl = nUrl + oUrl.substring(endPos + 1, oUrl.length());
		}
		return nUrl;
	}

	private static String __ENCODE__ = "GBK";
	private static String __SERVER_ENCODE__ = "UTF-8";

	public static int compareChinese(String s1, String s2) {
		String m_s1 = null, m_s2 = null;
		try {
			// 先将两字符串编码成GBK
			m_s1 = new String(s1.getBytes(__SERVER_ENCODE__), __ENCODE__);
			m_s2 = new String(s2.getBytes(__SERVER_ENCODE__), __ENCODE__);
		} catch (Exception ex) {
			return s1.compareTo(s2);
		}

		int res = chineseCompareTo(m_s1, m_s2);
		return res;

	}

	// 获取一个汉字/字母的Char值
	private static int getCharCode(String s) {
		if (s == null && s.equals(""))
			return -1;

		byte[] b = s.getBytes();

		int value = 0;

		// 保证取第一个字符（汉字或者英文）

		for (int i = 0; i < b.length && i <= 2; i++) {
			value = value * 100 + b[i];
		}
		return value;

	}

	// 比较两个字符串
	private static int chineseCompareTo(String s1, String s2) {
		int len1 = s1.length();
		int len2 = s2.length();
		int n = Math.min(len1, len2);
		for (int i = 0; i < n; i++) {
			int s1_code = getCharCode(s1.charAt(i) + "");
			int s2_code = getCharCode(s2.charAt(i) + "");

			if (s1_code != s2_code)
				return s1_code - s2_code;
		}
		return len1 - len2;
	}

	public static String removeHttpOrHttps(String origin) {
		if (origin == null)
			return "";
		if (origin.toLowerCase().startsWith("http://")) {
			return origin.substring(7, origin.length());
		}
		if (origin.toLowerCase().startsWith("https://")) {
			return origin.substring(8, origin.length());
		}
		return origin;
	}

	public static String getStringBySer(Serializable serializable) {
		if (null == serializable)
			return null;
		return serializable.toString();
	}

	public static boolean isEmpty(Long str) {
		if (null == str || ("").equals(str)) {
			return true;
		}
		return false;
	}

	/**
	 * 如果str为null或空字符串返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(String str) {
		return isNullOrEmpty(str);
	}

	public static Date buildDate(String dateStr) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return sf.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取流水号
	 * 
	 * @param length
	 * @param index
	 * @return
	 */
	public static String getLineNumber(int length, int index) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < length; i++) {
			buf.append("0");
		}
		buf.append(index + "");
		return buf.toString().substring(buf.length() - length);
	}

	/**
	 * 验证手机号，11位，且必须含全是数字 目前全国有27种手机号段。
	 * 移动有16个号段：134、135、136、137、138、139、147、150、
	 * 151、152、157、158、159、182、187、188。其中147、157、188是3G号段，其他都是2G号段。
	 * 联通有7种号段：130、131、132、155、156、185、186。其中186是3G（WCDMA）号段，其余为2G号段。
	 * 电信有4个号段：133、153、180、189。其中189是3G号段（CDMA2000），133号段主要用作无线网卡号。
	 * 130、131、132、133、134、135、136、137、138、139 十个
	 * 150、151、152、153、155、156、157、158、159 九个 180、182、185、186、187、188、189 七个
	 * 13、15、18三个号段共30个号段，154、181、183、184暂时没有，加上147共27个。
	 */
	public static boolean isMoble(String mobile) {
		/*
		 * Pattern p =
		 * Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
		 * Matcher m = p.matcher(mobile); return m.matches();
		 */
		// return mobile.matches("^\\d{11}$");
		return mobile.matches("^(13|14|15|18)\\d{9}$"); // 不做太严格的判断
	}

	/**
	 * 
	 * @author ChenRen
	 * @param is
	 * @return
	 */
	public static String inputStream2String(InputStream is) {
		StringBuffer sb = new StringBuffer();
		byte[] byt = new byte[4096]; // 4k
		int i = -1;
		try {
			while ((i = is.read(byt)) != -1) {
				sb.append(new String(byt, 0, i));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	private final static Pattern EMAILE = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");

	/**
	 * 判断是不是一个合法的电子邮件地址
	 * 
	 * @author ChenRen
	 * @param email
	 * @return
	 */
	public static boolean isEmail(String email) {
		if (isEmpty(email))
			return false;

		return EMAILE.matcher(email).matches();
	}

	public static String md5(String str) {
		if (StringTools.isNotEmpty(str)) {
			try {
				byte[] hash = MessageDigest.getInstance("MD5").digest(str.getBytes("UTF-8"));

				StringBuilder hex = new StringBuilder(hash.length * 2);
				for (byte b : hash) {
					if ((b & 0xFF) < 0x10)
						hex.append("0");
					hex.append(Integer.toHexString(b & 0xFF));
				}
				return hex.toString();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return EMPTY;
	}

	public static String ListToStr4Photo(List<String> list) {
		StringBuffer sb = new StringBuffer();
		for (int j = 0; j < list.size(); j++) {
			sb.append(list.get(j) + (j == list.size() - 1 ? "" : ","));
		}
		return sb.toString();
	}

	public static ArrayList<String> StrToList4Photo(String pic) {
		ArrayList<String> result = new ArrayList<String>();
		String[] temp = pic.split(",");
		if (temp.length >= 1 && !StringTools.isEmpty(temp[0]) ) {
			for (int i = 0; i < temp.length; i++) {
				result.add(temp[i]);
			}
		}
		return result;
	}


	public static String getVersionName(Context context) {
		String version = StringTools.EMPTY;
		try {
			version = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return version;
	}

	public static String getMyUUID(Context context) {
		final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		final String tmDevice, tmSerial, androidId;
		tmDevice = "" + tm.getDeviceId();
		tmSerial = "" + tm.getSimSerialNumber();
		androidId = "" + android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
		UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
		String uniqueId = deviceUuid.toString();
		return uniqueId;
	}

}